/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.kingbull.recorder.slice;

import com.kingbull.recorder.ResourceTable;
import com.kingbull.recorder.util.ResUtil;
import com.omrecorder.Recorder;
import com.omrecorder.OmRecorder;
import com.omrecorder.PullTransport;
import com.omrecorder.PullableSource;
import com.omrecorder.AudioChunk;
import com.omrecorder.WriteAction;
import com.omrecorder.LogUtil;
import com.omrecorder.AudioRecordConfig;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Environment;
import ohos.media.audio.AudioStreamInfo;

import java.io.File;


public class PcmRecorderAbilitySlice extends AbilitySlice {
    Recorder recorder;
    Image recordButton;
    Checkbox skipSilence;
    private Button pauseResumeButton;
    private AnimatorProperty recordButtonAnimation;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_recorder);
        setupRecorder();

        skipSilence = (Checkbox) findComponentById(ResourceTable.Id_skipSilence);
        skipSilence.setChecked(false);
        skipSilence.setEnabled(!false);
        if (skipSilence.isChecked()) {
            setAbsButtonBackgroundElement(skipSilence, ResourceTable.Media_abc_btn_check_to_on_mtrl_015, true);
        } else {
            setAbsButtonBackgroundElement(skipSilence, ResourceTable.Media_abc_btn_check_to_on_mtrl_000, false);
        }

        skipSilence.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (skipSilence.isChecked()) {
                    setAbsButtonBackgroundElement(skipSilence, ResourceTable.Media_abc_btn_check_to_on_mtrl_015, true);
                    setupNoiseRecorder();
                } else {
                    setAbsButtonBackgroundElement(skipSilence, ResourceTable.Media_abc_btn_check_to_on_mtrl_000, false);
                    setupRecorder();
                }
            }
        });

        recordButton = (Image) findComponentById(ResourceTable.Id_recordButton);
        recordButton.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                recorder.startRecording();
                skipSilence.setChecked(false);
                skipSilence.setEnabled(false);
                skipSilence.setTextColor(Color.GRAY);
            }
        });


        findComponentById(ResourceTable.Id_stopButton).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                try {
                    recorder.stopRecording();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                skipSilence.setChecked(true);
                skipSilence.setEnabled(true);
                skipSilence.setTextColor(Color.BLACK);
            }
        });
        pauseResumeButton = (Button) findComponentById(ResourceTable.Id_pauseResumeButton);
        pauseResumeButton.setClickedListener(new Component.ClickedListener() {
            boolean isPaused = false;

            @Override
            public void onClick(Component component) {
                if (recorder == null) {
                    ToastDialog toastDialog = new ToastDialog(getContext());
                    toastDialog.setText("Please start recording first!").setDuration(1000).show();
                    return;
                }
                if (!isPaused) {
                    pauseResumeButton.setText("RESUME_RECORDING");
                    recorder.pauseRecording();
                } else {
                    pauseResumeButton.setText("PAUSE RECORDING");
                    recorder.resumeRecording();
                }
                isPaused = !isPaused;
            }
        });

    }

    @Override
    protected void onStop() {
        super.onStop();
        try {
            recorder.stopRecording();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onBackPressed() {
        super.onBackPressed();
        try {
            recorder.stopRecording();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * This method is used to set background element & background color of radiobutton & checkbox
     *
     * @param absButton Radiobutton/Checkbox
     * @param drawable  Resource drawable for checked/uncheked
     * @param disabled  disabled state to set the color
     */
    private void setAbsButtonBackgroundElement(AbsButton absButton, int drawable, boolean disabled) {
        absButton.setButtonElement(ResUtil.getPixelMapDrawable(getContext(), drawable));
    }

    private void setupRecorder() {
        recorder = OmRecorder.pcm(
                new PullTransport.Default(mic(), new PullTransport.OnAudioChunkPulledListener() {
                    @Override public void onAudioChunkPulled(AudioChunk audioChunk) {
                        animateVoice((float) (audioChunk.maxAmplitude() / 200.0));
                    }
                }), file());
    }

    private void setupNoiseRecorder() {
        recorder = OmRecorder.pcm(
                new PullTransport.Noise(mic(),
                        new PullTransport.OnAudioChunkPulledListener() {
                            @Override public void onAudioChunkPulled(AudioChunk audioChunk) {
                                animateVoice((float) (audioChunk.maxAmplitude() / 200.0));
                            }
                        },
                        new WriteAction.Default(),
                        new Recorder.OnSilenceListener() {
                            @Override public void onSilence(long silenceTime) {
                                LogUtil.error("silenceTime", String.valueOf(silenceTime));
                                ToastDialog toastDialog = new ToastDialog(getContext());
                                toastDialog.setText("silence of " + silenceTime + " detected").setDuration(1000).show();
                            }
                        }, 200
                ), file()
        );
    }

    private void animateVoice(final float maxPeak) {
        recordButtonAnimation = new AnimatorProperty(recordButton);
        recordButtonAnimation.scaleX(1 + maxPeak).scaleY(1+maxPeak).setDuration(10).start();
    }

    private PullableSource mic() {
        return new PullableSource.Default(
                new AudioRecordConfig.Default(
                        ohos.media.recorder.Recorder.AudioSource.MIC, AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT,
                        AudioStreamInfo.ChannelMask.CHANNEL_IN_MONO, 44100
                )
        );
    }

    private File file() {
        String str = getContext().getExternalFilesDir(Environment.DIRECTORY_MUSIC) + File.separator + "kailashdabhi.pcm";
        return new File(str);
    }
}
